home *** CD-ROM | disk | FTP | other *** search
/ Language/OS - Multiplatform Resource Library / LANGUAGE OS.iso / gnu / emacs.lha / emacs-19.16 / lib-src / tcp.c < prev    next >
C/C++ Source or Header  |  1993-05-24  |  6KB  |  242 lines

  1. /*
  2.  * TCP/IP stream emulation for GNU Emacs.
  3.  * Copyright (C) 1988, 1989, 1992, 1993 Free Software Foundation, Inc.
  4.  
  5.  * Author: Masanobu Umeda
  6.  * Maintainer: umerin@mse.kyutech.ac.jp
  7.  
  8. This file is part of GNU Emacs.
  9.  
  10. GNU Emacs is free software; you can redistribute it and/or modify
  11. it under the terms of the GNU General Public License as published by
  12. the Free Software Foundation; either version 2, or (at your option)
  13. any later version.
  14.  
  15. GNU Emacs is distributed in the hope that it will be useful,
  16. but WITHOUT ANY WARRANTY; without even the implied warranty of
  17. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  18. GNU General Public License for more details.
  19.  
  20. You should have received a copy of the GNU General Public License
  21. along with GNU Emacs; see the file COPYING.  If not, write to
  22. the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
  23.  
  24.  *
  25.  * Yasunari, Itoh at PFU limited contributed for Fujitsu UTS and SX/A.
  26.  *
  27.  * Thu Apr  6 13:47:37 JST 1989
  28.  * USG fixes by Sakaeda <saka@mickey.trad.pf.fujitsu.junet>
  29.  *
  30.  * For Fujitsu UTS compile with:
  31.  *    cc -O -o tcp tcp.c -DFUJITSU_UTS -lu -lsocket
  32.  */
  33.  
  34. #include <stdio.h>
  35. #include <fcntl.h>
  36. #include <ctype.h>
  37. #include <sys/types.h>
  38.  
  39. #ifdef FUJITSU_UTS
  40. #define USG
  41. #include <sys/ucbtypes.h>
  42. #include <sys/tisp/socket.h>
  43. #include <netdb.h>
  44. #include <sys/tisp/in.h>
  45. #else
  46. #include <sys/socket.h>
  47. #include <netdb.h>
  48. #include <netinet/in.h>
  49. #endif
  50.  
  51. #ifdef USG
  52. #include <sys/stat.h>
  53. #include <signal.h>
  54. #endif
  55.  
  56. #ifdef FUJITSU_UTS
  57. #define bcopy(f, t, n)    memcpy (t, f, n)
  58. #define bcmp(b1, b2, n)   (memcmp (b1, b2, n)!=0)
  59. #define bzero(b, n)      memset (b, 0, n)
  60. #endif
  61.  
  62. #ifdef USG
  63. int selectable = 1;
  64.  
  65. sigout ()
  66. {
  67.   fcntl (fileno (stdin), F_SETFL, 0);
  68.   exit (-1);
  69. }
  70. #endif
  71.  
  72. main (argc, argv)
  73.      int argc;
  74.      char *argv[];
  75. {
  76.   struct hostent    *host;
  77.   struct sockaddr_in    sockin, sockme;
  78.   struct servent    *serv;
  79.   char    *hostname = NULL;
  80.   char    *service = "nntp";
  81.   int    port;
  82.   int    readfds;
  83.   int   writefds;
  84.   int    server;            /* NNTP Server */
  85.   int    emacsIn = fileno (stdin); /* Emacs intput */
  86.   int    emacsOut = fileno (stdout); /* Emacs output */
  87.   char    buffer[1024];
  88.   int    nbuffer;        /* Number of bytes in buffer */
  89.   int   wret;
  90.   char  *retry;            /* retry bufferp */
  91.   int   false = 0;        /* FALSE flag for setsockopt () */
  92.  
  93.   if (argc < 2)
  94.     {
  95.       fprintf (stderr, "Usage: %s HOST [SERVICE]\n", argv[0]);
  96.       exit (1);
  97.     }
  98.   if (argc >= 2)
  99.     hostname = argv[1];
  100.   if (argc >= 3)
  101.     service = argv[2];
  102.  
  103.   if ((host = gethostbyname (hostname)) == NULL)
  104.     {
  105.       perror ("gethostbyname");
  106.       exit (1);
  107.     }
  108.   if (isdigit (service[0]))
  109.     port = atoi (service);
  110.   else
  111.     {
  112.       serv = getservbyname (service, "tcp");
  113.       if (serv == NULL)
  114.     {
  115.       perror ("getservbyname");
  116.       exit (1);
  117.     }
  118.       port = serv->s_port;
  119.     }
  120.  
  121.   bzero (&sockin, sizeof (sockin));
  122.   sockin.sin_family = host->h_addrtype;
  123.   bcopy (host->h_addr, &sockin.sin_addr, host->h_length);
  124.   sockin.sin_port = port;
  125.   if ((server = socket (AF_INET, SOCK_STREAM, 0)) < 0)
  126.     {
  127.       perror ("socket");
  128.       exit (1);
  129.     }
  130.   if (setsockopt (server, SOL_SOCKET, SO_REUSEADDR, &false, sizeof (false)))
  131.     {
  132.       perror ("setsockopt");
  133.       exit (1);
  134.     }
  135.   bzero (&sockme, sizeof (sockme));
  136.   sockme.sin_family = sockin.sin_family;
  137.   sockme.sin_addr.s_addr = INADDR_ANY;
  138.   if (bind (server, &sockme, sizeof (sockme)) < 0)
  139.     {
  140.       perror ("bind");
  141.       exit (1);
  142.     }
  143.   if (connect (server, &sockin, sizeof (sockin)) < 0)
  144.     {
  145.       perror ("connect");
  146.       close (server);
  147.       exit (1);
  148.     }
  149.  
  150. #ifdef O_NDELAY
  151.   fcntl (server, F_SETFL, O_NDELAY);
  152.  
  153. #ifdef USG
  154.   /* USG pipe cannot not select emacsIn */
  155.   {
  156.     struct stat statbuf;
  157.     fstat (emacsIn, &statbuf);
  158.     if (statbuf.st_mode & 010000)
  159.       selectable = 0;
  160.     if (!selectable)
  161.       {
  162.     signal (SIGINT, sigout);
  163.     fcntl (emacsIn, F_SETFL, O_NDELAY);
  164.       }
  165.   }
  166. #endif
  167. #endif
  168.  
  169.   /* Connection established. */
  170.   while (1)
  171.     {
  172.       readfds = (1 << server) | (1 << emacsIn);
  173.       if (select (32, &readfds, NULL, NULL, (struct timeval *)NULL) == -1)
  174.     {
  175.       perror ("select");
  176.       exit (1);
  177.     }
  178.       if (readfds & (1 << emacsIn))
  179.     {
  180.       /* From Emacs */
  181.       nbuffer = read (emacsIn, buffer, sizeof buffer -1);
  182.  
  183. #ifdef USG
  184.       if (selectable && nbuffer == 0)
  185.         {
  186.           goto finish;
  187.         }
  188.       else if (!(readfds & (1 << server)) && nbuffer == 0)
  189.         {
  190.           sleep (1);
  191.         }
  192.       else 
  193. #else
  194.         if (nbuffer == 0)
  195.           goto finish;
  196. #endif
  197.       for (retry = buffer; nbuffer > 0; nbuffer -= wret, retry += wret)
  198.         {
  199.           writefds = 1 << server;
  200.           if (select (server+1, NULL, &writefds, NULL, (struct timeval*)NULL) == -1)
  201.         {
  202.           perror ("select");
  203.           exit (1);
  204.         }
  205.           wret = write (server, retry, nbuffer);
  206.           if (wret < 0) goto finish;
  207.         }
  208.     }
  209.       if (readfds & (1 << server))
  210.     {
  211.       /* From NNTP server */
  212.       nbuffer = read (server, buffer, sizeof buffer -1);
  213.       if (nbuffer == 0)
  214.         goto finish;
  215.       for (retry = buffer; nbuffer > 0; nbuffer -= wret, retry += wret)
  216.         {
  217.           writefds = 1 << emacsOut;
  218. #ifdef USG
  219.           if (selectable)
  220. #endif
  221.         if (select (emacsOut+1, NULL, &writefds, NULL, (struct timeval*)NULL) == -1)
  222.           {
  223.             perror ("select");
  224.             exit (1);
  225.           }
  226.           wret = write (emacsOut, retry, nbuffer);
  227.           if (wret < 0) goto finish;
  228.         }
  229.     }
  230.     }
  231.  
  232.   /* End of communication. */
  233.  finish:
  234.   close (server);
  235. #ifdef USG
  236.   if (!selectable) fcntl (emacsIn, F_SETFL, 0);
  237. #endif
  238.   close (emacsIn);
  239.   close (emacsOut);
  240.   exit (0);
  241. }
  242.